package org.aalku.util.classLoaders.maven;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.Arrays;
import java.util.HashSet;
import java.util.LinkedHashSet;

public class MavenClassLoader extends URLClassLoader {

	private static final String MAVEN_PREFIX = "maven://";
	private LinkedHashSet<String> repositories = new LinkedHashSet<String>();

	/**
	 * Just a sample
	 * @throws IOException 
	 */
	public static void main(String[] args) throws ClassNotFoundException,
			InstantiationException, IllegalAccessException, SecurityException,
			NoSuchMethodException, IllegalArgumentException,
			InvocationTargetException, IOException {
		MavenClassLoader x = new MavenClassLoader();
		x.addRepositoryURL("http://uk.maven.org/maven2/");
		x.addClasspathElements(new File("maven-classpath.cfg"));

		Class<?> myClazz = x
				.loadClass("org.springframework.context.support.ClassPathXmlApplicationContext");
		Object myObject = myClazz.newInstance();
		System.out.println(System.getProperty("java.class.path"));
		System.out.println(myObject);
		// TODO

	}

	public void addClasspathElements(File file) throws IOException {
		BufferedReader r = new BufferedReader(new FileReader(file));
		try {
			String line;
			while ((line = r.readLine()) != null) {
				addClasspathURL(line);
			}
		} finally {
			r.close();
		}
	}

	public void addClasspathURL(String url) {
		HashSet<URL> added = new HashSet<URL>(Arrays.asList(getURLs()));
		for (String rep : repositories) {
			URL artifactUrl;
			try {
				if (url.startsWith(MAVEN_PREFIX)) {
					artifactUrl = new URL(url.replace(MAVEN_PREFIX, rep));
				} else {
					artifactUrl = new URL(url);
				}
			} catch (MalformedURLException e) {
				throw new RuntimeException(e);
			}
			if (added.add(artifactUrl)) {
				// List<Artifact> pomDependencies = null;
				try {
					// pomDependencies = getArtifactDependencies(rep, a);
					// addArtifactImpl(pomDependencies, false);

					addURL(artifactUrl);

					System.out.println("Added URL: " + artifactUrl);
				} catch (Exception e) {
					System.out.println("Invalid artifact URL: " + artifactUrl);
					added.remove(artifactUrl);
				}
			}
		}
	}

	public MavenClassLoader() {
		super(new URL[0]);
	}

	public void addStringURL(String url) {
		try {
			addURL(new URL(url));
		} catch (MalformedURLException e) {
			throw new RuntimeException(e);
		}
	}

	@Override
	protected Class<?> findClass(String name) throws ClassNotFoundException {
		Class<?> clazz;
		boolean ok = false;
		try {
			clazz = super.findClass(name);
			ok = true;
		} finally {
			System.out.println(String.format("findClass(%s):%s%n", name, ok));
		}
		return clazz;
	}

	public synchronized void addRepositoryURL(String url) {
		repositories.add(url);
	}

}
